package erfgame.core.util;

import org.junit.Test;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;


import erfgame.core.util.ArrayUtils;
import erfgame.core.world.terrain.TerrainUpdate;
import erfgame.core.world.terrain.TerrainUtils;

public class UpdateSummarySurfacesTester {
	
	@Test
	public void testEmptyMerge() {
		short[] terrainXY = new short[]{0,0,0,1,1,1,1,0,0,0};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{};
		int[] summaryXY = new int[3];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, 0, 10-1, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{3,7} ) );
	}
	
	@Test
	public void testWipedMerge() {
		short[] terrainXY = new short[]{0,0,0,1,1,1,1,0,0,0};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{1,2,3,4,5};
		int[] summaryXY = new int[3];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, 0, 10-1, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{3,7} ) );
	}

	@Test
	public void testVoidMerge() {
		short[] terrainXY = new short[]{0,TerrainUpdate.FLAG_OVERWRITE_IF_AIR,0,1,1,1,1,0,0,0};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{1,2,3,4,5,6};
		int[] summaryXY = new int[5];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, 0, 10-1, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{1,2,3,7} ) );
	}

	@Test
	public void testExtendedMerge() {
		short[] terrainXY = new short[]{0,0,1,1,0,0};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{1,2,3,4,5,6,7,8,9,10};
		int[] summaryXY = new int[3];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int start = 3;
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, start, start+terrainXY.length-1, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{1,2,5,7,9,10} ) );
	}

	@Test
	public void testExtendedMerge2() {
		short[] terrainXY = new short[]{TerrainUpdate.FLAG_OVERWRITE_IF_AIR,1,1,1,TerrainUpdate.FLAG_OVERWRITE_IF_AIR,0};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{1,2,3,4,5,6,7,8,9,10};
		int[] summaryXY = new int[4];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int start = 3;
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, start, start+terrainXY.length-1, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{1,2,3,8,9,10} ) );
	}

	@Test
	public void testSnipped() {
		short[] terrainXY = new short[]{1,1,1,0,0,0,1,1,1};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{0,3,6,9};
		int[] summaryXY = new int[3];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int start = -3;
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, start, start+terrainXY.length-1, new int[1]);
		// this test case is bullshit
		assertTrue( ArrayUtils.equals( result, new int[]{-3, 0, 3,9} ) );		
	}
	
	@Test
	public void testReal() {
		short x = TerrainUpdate.FLAG_OVERWRITE_IF_AIR;
		short[] terrainXY = new short[]{x,x,x,x,0,0,0,0,0,0,x,x,x,x};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{48,140};
		int[] summaryXY = new int[3];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int start = 41;
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, start, 54, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{51,140} ) );		
	}
	
	@Test
	public void testReal2() {
		short x = TerrainUpdate.FLAG_OVERWRITE_IF_AIR;
		short[] terrainXY = new short[]{x,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,x};
		int[] temp = new int[100];
		int[] surfacesXY = new int[]{66,140};
		int[] summaryXY = new int[3];
		TerrainUtils.deriveTerrainSummary( terrainXY, summaryXY );
		int start = 57;
		int[] result = TerrainUtils.updateSurfaces(temp, surfacesXY, terrainXY, summaryXY, start, 74, new int[1]);
		assertTrue( ArrayUtils.equals( result, new int[]{74,140} ) );		
	}

	@Test
	public void testReal3() {
		int[] temp = new int[256];
		int startz = 38;
		int endz = 77;
		short x = TerrainUpdate.FLAG_OVERWRITE_IF_AIR;
		short[] terrain = {x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,0,0,0,0,0,0,0,0,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x};
		int[] summary = {16,8,16};
		int[] surface = {52,140};
		int[] result = TerrainUtils.updateSurfaces(temp, surface, terrain, summary, startz, endz, new int[1]);
		int[] expected = {52,54,62,140};
		assertNotNull( result );
		assertTrue( ArrayUtils.equals(result, expected) );
	}


}
